// Api/Controllers/FilesController.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using UniversalAdmin.Api.Models;
using UniversalAdmin.Application.Services;
using UniversalAdmin.Application.DTOs;
using UniversalAdmin.Application.Common;
using UniversalAdmin.Infrastructure.Options;
using Microsoft.Extensions.Options;

namespace UniversalAdmin.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class FilesController : ControllerBase
{
  private readonly IFileService _fileManager;
  private readonly FileStorageOptions _fileStorageOptions;

  public FilesController(IFileService fileManager, IOptions<FileStorageOptions> fileStorageOptions)
  {
    _fileManager = fileManager;
    _fileStorageOptions = fileStorageOptions.Value;
  }

  [HttpPost("upload")]
  public async Task<IActionResult> Upload(IFormFile file, CancellationToken ct)
  {
    Console.WriteLine("FilesController.Upload called");
    
    if (file == null || file.Length == 0)
    {
      Console.WriteLine("文件为空或长度为0");
      return BadRequest(ApiResponse.Error(400, "请选择文件"));
    }

    Console.WriteLine($"文件信息: 名称={file.FileName}, 大小={file.Length}, 类型={file.ContentType}");

    try
    {
      await using var memoryStream = new MemoryStream();
      await file.CopyToAsync(memoryStream, ct);
      memoryStream.Position = 0;
      
      // 安全地获取用户ID
      var userIdClaim = User.FindFirstValue(ClaimTypes.NameIdentifier);
      var userId = string.IsNullOrEmpty(userIdClaim) ? 1 : int.Parse(userIdClaim); // 临时使用默认用户ID
      
      Console.WriteLine($"用户ID: {userId}");
      
      await using var stream = file.OpenReadStream();

      var res = await _fileManager.UploadAsync(
          stream, file.FileName, file.ContentType, file.Length, userId, ct);

      Console.WriteLine($"文件服务返回结果: Code={res.Code}, Message={res.Message}");

      return res.Code == 200
          ? Ok(res)
          : BadRequest(res);
    }
    catch (Exception ex)
    {
      Console.WriteLine($"文件上传错误: {ex.Message}");
      Console.WriteLine($"错误堆栈: {ex.StackTrace}");
      return BadRequest(ApiResponse.Error(500, $"文件上传失败: {ex.Message}"));
    }
  }

  [HttpGet]
  public async Task<IActionResult> GetMyFiles(
      [FromQuery] int page = 1,
      [FromQuery] int size = 10,
      [FromQuery] string? keyword = null,
      [FromQuery] string? mimeType = null,
      [FromQuery] string? userName = null,
      CancellationToken ct = default)
  {
    var userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? "");
    var param = new FileQueryParameters { Page = page, Size = size, Keyword = keyword, MimeType = mimeType, UserId = userId, UserName = userName };
    var res = await _fileManager.GetFilesAsync(param, ct);
    return Ok(ApiResponse<PagedResult<FileDto>>.Success(res, "获取成功"));
  }

  [HttpGet("{id:int}/download")]
  [Authorize]
  public async Task<IActionResult> Download(int id, CancellationToken ct)
  {
    try
    {
      var userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
      var result = await _fileManager.GetFileByIdAsync(id, userId, ct);

      if (!result.Ok || result.Data == null)
        return NotFound(ApiResponse.Error(404, "文件不存在"));

      // 构建绝对路径
      var relativePath = result.Data.Path.TrimStart('/');
      var fullPath = Path.Combine(_fileStorageOptions.RootPath, relativePath);
      var absolutePath = Path.GetFullPath(fullPath);
      
      // 添加调试信息
      Console.WriteLine($"Download request for file ID: {id}");
      Console.WriteLine($"File path from DB: {result.Data.Path}");
      Console.WriteLine($"Root path: {_fileStorageOptions.RootPath}");
      Console.WriteLine($"Relative path: {relativePath}");
      Console.WriteLine($"Full path: {fullPath}");
      Console.WriteLine($"Absolute path: {absolutePath}");
      Console.WriteLine($"File exists: {System.IO.File.Exists(absolutePath)}");

      if (!System.IO.File.Exists(absolutePath))
        return NotFound(ApiResponse.Error(404, "物理文件不存在"));

      // 设置中文文件名编码
      var encodedFileName = System.Net.WebUtility.UrlEncode(result.Data.OriginalName);
      Response.Headers.Append("Content-Disposition", $"attachment; filename*=UTF-8''{encodedFileName}");

      return PhysicalFile(absolutePath, result.Data.MimeType);
    }
    catch (Exception ex)
    {
      Console.WriteLine($"Download error: {ex.Message}");
      Console.WriteLine($"Stack trace: {ex.StackTrace}");
      return StatusCode(500, ApiResponse.Error(500, $"下载失败: {ex.Message}"));
    }
  }

  [HttpDelete("{id:int}")]
  public async Task<IActionResult> DeleteFile(int id, CancellationToken ct)
  {
    var userId = int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
    var res = await _fileManager.DeleteAsync(id, userId, ct);
    return res.Code == 200
        ? Ok(res)
        : BadRequest(res);
  }
}